package keye.document_manage.util;

import java.io.File;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

@Component("dynamicCreateDataSourceBean")
public class DynamicCreateDataSourceBean implements ApplicationContextAware, ApplicationListener<ApplicationEvent>{

	@Resource
	private ConfigurableApplicationContext applicationContext;

	@Resource
	private MultipleDataSource multipleDataSource;
	
	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		if (event instanceof ContextRefreshedEvent) {
//            init();
//			System.out.println(applicationContext.getBean("sqliteDatas"));
//			addSourceBeanToApp();
//			System.out.println(applicationContext.getBean("sqliteDatas"));
        }
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = (ConfigurableApplicationContext)applicationContext;
	}
	
	@SuppressWarnings("unchecked")
	public void addSourceBeanToApp(String path,String beanKey){
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
		String DATASOURCE_BEAN_CLASS = "org.apache.commons.dbcp.BasicDataSource";
		BeanDefinitionBuilder bdb;
		Map<Object, Object> targetDataSources = new LinkedHashMap<Object, Object>();

		bdb = BeanDefinitionBuilder.rootBeanDefinition(DATASOURCE_BEAN_CLASS);  
		bdb.getBeanDefinition().setAttribute("id", beanKey);
		bdb.getBeanDefinition().setAttribute("destroy-method", "close");
		bdb.addPropertyValue("driverClassName", "org.sqlite.JDBC");  
		bdb.addPropertyValue("url", "jdbc:sqlite:"+path+File.separator+"archive.db");  
		bdb.addPropertyValue("username", "");  
		bdb.addPropertyValue("password", "");  
		bdb.addPropertyValue("timeBetweenEvictionRunsMillis", 3600000);  
		bdb.addPropertyValue("minEvictableIdleTimeMillis", 3600000);  
		//  注册bean  
		beanFactory.registerBeanDefinition(beanKey, bdb.getBeanDefinition());  

		//  放入map中，注意一定是刚才创建bean对象  
		targetDataSources.put(beanKey, applicationContext.getBean(beanKey));  
		Class<?> clazz=(Class<?>) multipleDataSource.getClass().getSuperclass();
		try {
			Field f = clazz.getField("targetDataSources");
			f.setAccessible(true);
			((Map<Object, Object>)f.get(multipleDataSource)).put(beanKey, applicationContext.getBean(beanKey));
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (BeansException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		multipleDataSource.setTargetDataSources(targetDataSources );
		multipleDataSource.afterPropertiesSet();  
		
		MultipleDataSource.setDatasourceKey(beanKey);
		MultipleDataSource.setDialect(MultipleDataSource.SQLITE);
	}

	public void removeBean(String beanName){
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
		beanFactory.removeBeanDefinition(beanName);
	}
	
	public void setMultipleDataSource(MultipleDataSource multipleDataSource) {
		this.multipleDataSource = multipleDataSource;
	}
}
